﻿#ifndef HARRISDETECTOR_H
#define HARRISDETECTOR_H

#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"

/**
 * @brief The HarrisDetector class Harris 角点检测
 * 代码取自 OpenCV3 Computer Vision Application Programming Cookbook
 * 略做了写小的修改
 */
class HarrisDetector
{
public:
    HarrisDetector();
    void setLocalMaxWindowSize(int size);
    /**
     * @brief detect 计算出所有的角点，去除了相邻像素。但是还会比我们需要的角点多。
     *               所以还需要用 getCorners 函数进一步过滤掉一些强度偏低的。
     *               之所以分成 detect 和 getCorners 两步是因为 qualityLevel 取值有可能需要多次实验。
     *               而 detect 的运算量较大。分成两步我们就只需要重复 getCorners。
     * @param image
     */
    void detect(const cv::Mat& image);
    /**
     * @brief getCornerMap 获得强度大于 qualityLevel 的角点
     * @param qualityLevel 0-1 1 表示图中最强的角点。
     * @return 返回一个 CV_8U 类型矩阵，值为 255 的地方是角点
     */
    cv::Mat getCornerMap(double qualityLevel);
    void getCorners(std::vector<cv::Point> &points, double qualityLevel);
    void getCorners(std::vector<cv::Point> &points, const cv::Mat& cornerMap);
    /**
     * @brief drawOnImage 将图中的角点圈出来
     * @param image
     * @param points
     * @param color
     * @param radius
     * @param thickness
     */
    void drawOnImage(cv::Mat &image, const std::vector<cv::Point> &points,
                     cv::Scalar color = cv::Scalar(255,255,255),
                     int radius = 3, int thickness = 2);
private:

   cv::Mat m_cornerStrength;  // 32-bit float image of corner strength
   cv::Mat m_cornerTh;  // 32-bit float image of thresholded corners
   cv::Mat m_localMax;  // image of local maxima (internal)
   int m_neighbourhood;    // size of neighbourhood for derivatives smoothing
   int m_aperture;   // aperture for gradient computation
   double m_k;  // Harris parameter
   double m_maxStrength;  // maximum strength for threshold computation
   double m_threshold;  // calculated threshold (internal)
   int m_nonMaxSize;   // size of neighbourhood for non-max suppression
   cv::Mat m_kernel;  // kernel for non-max suppression

};

#endif // HARRISDETECTOR_H
